package com.lagou.cluster.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.lagou.cluster.entity.JobInfo;
import com.lagou.cluster.mapper.JobInfoMapper;
import org.redisson.api.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

@Service
public class JobInfoMapService {
    @Autowired
    private JobInfoMapper jobInfoMapper;

    private RedissonClient redissonClient;

    private Logger log  = LoggerFactory.getLogger(JobInfoMapService.class);

    @Autowired
    public void setRedissonClient(RedissonClient redissonClient) {
       this.redissonClient = redissonClient;
    }

    void init() {
        RBloomFilter filter = this.redissonClient.getBloomFilter("job_info_ids");
        filter.tryInit(1000000, 0.03);
        List<JobInfo> list = jobInfoMapper.selectList(new QueryWrapper<>());
        list.stream().map(JobInfo::getId).forEach(filter::add);
    }

    public JobInfo getById(int id) {
        RMapCache<Integer, JobInfo> map = redissonClient.getMapCache("job_info_map");
        JobInfo info = map.get(id);
        if (info == null) {
            info = this.jobInfoMapper.selectById(id);
            putCache(info);
        }
        return info;
    }

    public int save(JobInfo info) {
        int result = 0;
        if (info.getId() != null && info.getId()>0) {
            this.jobInfoMapper.updateById(info);
        } else {
            this.jobInfoMapper.insert(info);
        }
        putCache(info);
        return result;
    }

    void putCache(JobInfo info) {
        RMapCache<Integer, JobInfo> map = redissonClient.getMapCache("job_info_map");
        int random = ThreadLocalRandom.current().nextInt(100);
        map.put(info.getId(), info, 2 * 60 * 1000 + random, TimeUnit.MILLISECONDS);
    }

}
